package com.shchekoldin.juliet.packager.xml;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.ArrayList;
import java.util.List;

/**
 * Element for a group of files.
 */
public class GroupElement {

    /**
     * Group name.
     */
    @XmlElement
    private String name;

    /**
     * Parent group name.
     */
    @XmlElement(name = "parent")
    private String parentName;

    @XmlElement(name = "input-dir")
    private String inputDir;

    @XmlElement(name = "output-dir")
    private String outputDir;

    /**
     * List of files to include into current group.
     */
    @XmlElementWrapper(name = "include-files")
    @XmlElement(name = "file")
    private List<String> includeFiles = new ArrayList<String>();

    /**
     * List of files to exclude from current group.
     */
    @XmlElementWrapper(name = "exclude-files")
    @XmlElement(name = "file")
    private List<String> excludeFiles = new ArrayList<String>();

    @XmlElement(name = "custom-options")
    private Object customOptions;

    @XmlElement(name = "abstract")
    private Object abstractGroup;

    private GroupElement parent;

    private String filesExtension;

    // -------------------------------------------------------
    // -                        LOGIC                        -
    // -------------------------------------------------------

    private Element findCustomOption(String name) {
        if (customOptions == null) return null;

        Node option = ((Element) customOptions).getFirstChild();

        while (option != null) {
            if (option.getNodeName().equals(name)) break;
            option = option.getNextSibling();
        }

        return (Element) option;
    }

    //
    // API
    //

    public GroupElement() { }

    public GroupElement(String name, GroupElement parent) {
        this.name = name;
        this.parent = parent;
    }

    public String getInputDir() {
        return ((inputDir == null) && (parent != null)
            ? parent.getInputDir()
            : inputDir);
    }

    public String getOutputDir() {
        return ((outputDir == null) && (parent != null)
            ? parent.getOutputDir()
            : outputDir);
    }

    public Element getCustomOption(String name) {
        return getCustomOption(name, true);
    }

    public Element getCustomOption(String name, boolean recursive) {
        Element option = findCustomOption(name);
        return ((option == null) && (parent != null) && recursive
            ? parent.getCustomOption(name)
            : option);
    }

    public boolean isAbstract() {
        return (abstractGroup != null);
    }

    public String getFilesExtension() {
        if (filesExtension == null) {
            String firstFilePath = includeFiles.get(0);
            filesExtension = firstFilePath.substring(firstFilePath.lastIndexOf("."));
        }

        return filesExtension;
    }

    // -------------------------------------------------------
    // -                      GET & SET                      -
    // -------------------------------------------------------

    public String getName() {
        return name;
    }

    public String getParentName() {
        return parentName;
    }

    public List<String> getIncludeFiles() {
        return includeFiles;
    }

    public List<String> getExcludeFiles() {
        return excludeFiles;
    }

    public GroupElement getParent() {
        return parent;
    }

    public void setParent(GroupElement parent) {
        this.parent = parent;
    }

}
